﻿using System;
using System.Collections.Generic;
using System.Text;
using NHibernate;
using NHibernate.Criterion;

namespace OpenFuse.Cache.Repositories
{
    public class NodeRepository
    {
        public void Save(Node n)
        {
            using (ISession session = LocalCache.OpenSession())
			using (ITransaction transaction = session.BeginTransaction())
            {
				if(n.Parent == null)
					n.MangledPath = n.Name;
				else
					n.MangledPath = n.Parent.MangledPath + "/" + n.Name;

				session.SaveOrUpdate(n);
           		transaction.Commit();
            }
        }

        public void Update(Node n)
        {
            throw new NotImplementedException();
        }

        public void Remove(Node n)
        {
            throw new NotImplementedException();
        }

        public Node GetById(Guid ID)
        {
            using (ISession session = LocalCache.OpenSession())
            {
                return session.CreateCriteria(typeof(Node))
                    .Add(Restrictions.Eq("Id", ID))
                    .UniqueResult<Node>();
			}
        }

        public Node GetByPath(string path)
        {
            using (ISession session = LocalCache.OpenSession())
            {
                return session.CreateCriteria(typeof(Node))
                    .Add(Restrictions.Eq("MangledPath", path))
                    .UniqueResult<Node>();
            }
        }

		
        public Node GetByParentRowIdNameAndSerial(int parentRowId, string name, int serial)
        {
            using (ISession session = LocalCache.OpenSession())
            {
                return session.CreateCriteria(typeof(Node))
                    .Add(Restrictions.Eq("Parent.RowId", parentRowId))
                    .Add(Restrictions.Eq("Name", name))
                    .Add(Restrictions.Eq("NameSerial", serial))
                    .UniqueResult<Node>();
            }
        }

		public IList<Node> GetParentIdAndName(int parentId, string name)
        {
            using (ISession session = LocalCache.OpenSession())
            {
	            return session.CreateCriteria(typeof(Node))
					.Add(Restrictions.Eq("Parent", parentId))
                    .Add(Restrictions.Eq("Name", name))
					.List<Node>();
            }
        }

        public int CountByPath(string path)
        {
            using (ISession session = LocalCache.OpenSession())
            {
                int cnt = session.CreateCriteria(typeof(Node))
                    .Add(Restrictions.Eq("Path", path))
					.SetProjection(Projections.RowCount())
                    .UniqueResult<int>();
                return cnt;
            }
        }


        public void Delete(Node n)
        {
            using (ISession session = LocalCache.OpenSession())
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Delete(n);
                    transaction.Commit();
                }
        }

		public void DeleteAll()
		{
            using (ISession session = LocalCache.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
				{
					IList<Node> nodes = session.CreateCriteria(typeof(Node))
    	            						.Add(Restrictions.IsNull("Parent"))
											.List<Node>();
					foreach(Node n in nodes)
						session.Delete(n);
					session.Flush();
                    transaction.Commit();
                }
            }
		}
    }
}
